<template>
  <div class="page-content">
    <div class="header">
      <h3>节点管理</h3>
    </div>

    <div class="actions-bar">
      <el-row :gutter="20">
        <el-col :span="6">
          <el-input v-model="searchKeyword" placeholder="搜索节点..." clearable>
            <template #prefix>
              <el-icon><search /></el-icon>
            </template>
          </el-input>
        </el-col>
        <el-col :span="18" class="action-buttons">
          <el-button type="primary" @click="openAddNodeDialog" v-ripple>注册节点</el-button>
          <el-button @click="refresh" v-ripple>刷新列表</el-button>
          <el-button type="danger" @click="batchDelete" :disabled="selectedNodes.length === 0" v-ripple>
            批量删除
          </el-button>
        </el-col>
      </el-row>
    </div>

    <div class="node-stats">
      <el-row :gutter="20">
        <el-col :span="6">
          <el-card shadow="hover">
            <div class="stat-item">
              <div class="stat-icon online">
                <el-icon><circle-check /></el-icon>
              </div>
              <div class="stat-info">
                <div class="stat-title">在线节点</div>
                <div class="stat-value">{{ onlineCount }}</div>
              </div>
            </div>
          </el-card>
        </el-col>
        <el-col :span="6">
          <el-card shadow="hover">
            <div class="stat-item">
              <div class="stat-icon offline">
                <el-icon><circle-close /></el-icon>
              </div>
              <div class="stat-info">
                <div class="stat-title">离线节点</div>
                <div class="stat-value">{{ offlineCount }}</div>
              </div>
            </div>
          </el-card>
        </el-col>
        <el-col :span="6">
          <el-card shadow="hover">
            <div class="stat-item">
              <div class="stat-icon warning">
                <el-icon><warning /></el-icon>
              </div>
              <div class="stat-info">
                <div class="stat-title">异常节点</div>
                <div class="stat-value">{{ warningCount }}</div>
              </div>
            </div>
          </el-card>
        </el-col>
        <el-col :span="6">
          <el-card shadow="hover">
            <div class="stat-item">
              <div class="stat-icon total">
                <el-icon><connection /></el-icon>
              </div>
              <div class="stat-info">
                <div class="stat-title">总节点数</div>
                <div class="stat-value">{{ nodeList.length }}</div>
              </div>
            </div>
          </el-card>
        </el-col>
      </el-row>
    </div>

    <div class="node-table">
      <el-table
        v-loading="loading"
        :data="filteredNodes"
        stripe
        border
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" />
        <el-table-column prop="name" label="节点名称" min-width="150" />
        <el-table-column prop="ip" label="IP地址" width="140" />
        <el-table-column prop="port" label="端口" width="100" />
        <el-table-column prop="status" label="状态" width="100">
          <template #default="scope">
            <el-tag :type="getNodeStatusType(scope.row.status)">
              {{ getNodeStatusName(scope.row.status) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="updated_at" label="最后心跳时间" width="180" />
        <el-table-column fixed="right" label="操作" width="250">
          <template #default="scope">
            <el-button
              size="small"
              type="primary"
              @click="openDetail(scope.row)"
              plain
            >详情</el-button>
            <el-button
              size="small"
              type="success"
              @click="openConfig(scope.row)"
              plain
            >配置</el-button>
            <el-button
              size="small"
              type="danger"
              @click="removeNode(scope.row)"
              plain
            >删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <div class="pagination-container">
        <el-pagination
          v-model:current-page="currentPage"
          v-model:page-size="pageSize"
          :page-sizes="[10, 20, 50, 100]"
          layout="total, sizes, prev, pager, next, jumper"
          :total="filteredNodes.length"
        />
      </div>
    </div>

    <!-- 节点详情对话框 -->
    <el-dialog title="节点详情" v-model="detailVisible" width="60%">
      <el-descriptions :column="2" border>
        <el-descriptions-item label="节点ID">{{ currentNode.id }}</el-descriptions-item>
        <el-descriptions-item label="节点名称">{{ currentNode.name }}</el-descriptions-item>
        <el-descriptions-item label="服务类型">
          <el-tag>{{ getServiceTypeName(currentNode.type) }}</el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="状态">
          <el-tag :type="getStatusType(currentNode.status)">
            {{ getStatusName(currentNode.status) }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="IP地址">{{ currentNode.ip }}</el-descriptions-item>
        <el-descriptions-item label="端口">{{ currentNode.port }}</el-descriptions-item>
      </el-descriptions>
      
      <div class="node-detail-tabs">
        <el-tabs>
          <el-tab-pane label="资源使用">
            <div class="health-info">
              <el-row :gutter="20">
                <el-col :span="8">
                  <el-card>
                    <template #header>CPU 使用率</template>
                    <div class="metric">
                      <el-progress
                        type="dashboard"
                        :percentage="currentNode.cpuUsage || 0"
                        :color="getCpuColor"
                      />
                    </div>
                  </el-card>
                </el-col>
                <el-col :span="8">
                  <el-card>
                    <template #header>内存使用率</template>
                    <div class="metric">
                      <el-progress
                        type="dashboard"
                        :percentage="currentNode.memoryUsage || 0"
                        :color="getMemoryColor"
                      />
                    </div>
                  </el-card>
                </el-col>
                <el-col :span="8">
                  <el-card>
                    <template #header>磁盘使用率</template>
                    <div class="metric">
                      <el-progress
                        type="dashboard"
                        :percentage="currentNode.diskUsage || 0"
                        :color="getDiskColor"
                      />
                    </div>
                  </el-card>
                </el-col>
              </el-row>
            </div>
          </el-tab-pane>
          <el-tab-pane label="连接信息">
            <el-descriptions :column="2" border>
              <el-descriptions-item label="当前连接数">{{ currentNode.connectionCount }}</el-descriptions-item>
              <el-descriptions-item label="最大连接数">{{ currentNode.maxConnections }}</el-descriptions-item>
              <el-descriptions-item label="当前用户数">{{ currentNode.userCount }}</el-descriptions-item>
              <el-descriptions-item label="网络使用率">{{ currentNode.networkUsage }}%</el-descriptions-item>
              <el-descriptions-item label="最大网络使用">{{ currentNode.maxNetworkUsage }}%</el-descriptions-item>
              <el-descriptions-item label="最长连接时间">{{ currentNode.maxConnTime || '-' }}</el-descriptions-item>
            </el-descriptions>
          </el-tab-pane>
        </el-tabs>
      </div>
    </el-dialog>

    <!-- 节点配置对话框 -->
    <el-dialog
      :title="isEdit ? '编辑节点' : '注册节点'"
      v-model="configVisible"
      width="50%"
    >
      <el-form :model="configForm" :rules="configRules" ref="configFormRef" label-width="100px">
        <el-form-item label="节点名称" prop="name">
          <el-input v-model="configForm.name" placeholder="请输入节点名称" />
        </el-form-item>
        <el-form-item label="IP地址" prop="ip">
          <el-input v-model="configForm.ip" placeholder="请输入IP地址" />
        </el-form-item>
        <el-form-item label="端口" prop="port">
          <el-input-number v-model="configForm.port" :min="1" :max="65535" />
        </el-form-item>
        <el-form-item label="服务类型" prop="type">
          <el-select v-model="configForm.type" placeholder="请选择服务类型" style="width: 100%">
            <el-option label="Web服务" value="web" />
            <el-option label="数据库服务" value="database" />
            <el-option label="缓存服务" value="cache" />
            <el-option label="消息队列" value="mq" />
            <el-option label="文件服务" value="file" />
            <el-option label="其他服务" value="other" />
          </el-select>
        </el-form-item>
        <el-form-item label="描述" prop="description">
          <el-input
            type="textarea"
            v-model="configForm.description"
            placeholder="请输入节点描述"
            :rows="3"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="configVisible = false">取消</el-button>
          <el-button type="primary" @click="saveConfig">确定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  Search,
  CircleCheck,
  CircleClose,
  Warning,
  Connection
} from '@element-plus/icons-vue'
import type { FormInstance } from 'element-plus'
import { getNodeList } from '@/Newapi/device'

// 加载状态
const loading = ref(false)

// 搜索关键词
const searchKeyword = ref('')

// 分页
const currentPage = ref(1)
const pageSize = ref(10)

// 节点列表
const nodeList = ref<any[]>([])

// 选中的节点
const selectedNodes = ref<any[]>([])

// 是否为编辑模式
const isEdit = ref(false)

// 节点详情对话框
const detailVisible = ref(false)
const currentNode = reactive({
  id: '',
  name: '',
  ip: '',
  port: 0,
  type: '',
  status: '',
  description: '',
  registerTime: '',
  lastHeartbeat: '',
  apiVersion: '',
  systemInfo: '',
  cpuUsage: 0,
  memoryUsage: 0,
  diskUsage: 0,
  logs: [] as any[]
})

// 节点配置对话框
const configVisible = ref(false)
const configFormRef = ref<FormInstance>()
const configForm = reactive({
  id: '',
  name: '',
  ip: '',
  port: 8080,
  type: '',
  description: ''
})

// 表单验证规则
const configRules = {
  name: [
    { required: true, message: '请输入节点名称', trigger: 'blur' },
    { min: 2, max: 50, message: '长度在 2 到 50 个字符', trigger: 'blur' }
  ],
  ip: [
    { required: true, message: '请输入IP地址', trigger: 'blur' },
    { pattern: /^(\d{1,3}\.){3}\d{1,3}$/, message: '请输入有效的IP地址', trigger: 'blur' }
  ],
  port: [
    { required: true, message: '请输入端口号', trigger: 'blur' },
    { type: 'number', min: 1, max: 65535, message: '端口号范围为1-65535', trigger: 'blur' }
  ],
  type: [
    { required: true, message: '请选择服务类型', trigger: 'change' }
  ],
  description: [
    { required: false }
  ]
} as const

// 计算属性：过滤后的节点列表
const filteredNodes = computed(() => {
  if (!searchKeyword.value) {
    return nodeList.value
  }
  const keyword = searchKeyword.value.toLowerCase()
  return nodeList.value.filter(
    (node) =>
      node.name.toLowerCase().includes(keyword) ||
      node.ip.toLowerCase().includes(keyword)
  )
})

// 计算属性：在线节点数量
const onlineCount = computed(() => {
  return nodeList.value.filter((node) => node.status === 'online').length
})

// 计算属性：离线节点数量
const offlineCount = computed(() => {
  return nodeList.value.filter((node) => node.status === 'offline').length
})

// 计算属性：异常节点数量
const warningCount = computed(() => {
  return nodeList.value.filter((node) => node.status === 'warning').length
})

// CPU使用率颜色
const getCpuColor = (percentage: number) => {
  if (percentage < 70) return '#67c23a'
  if (percentage < 90) return '#e6a23c'
  return '#f56c6c'
}

// 内存使用率颜色
const getMemoryColor = (percentage: number) => {
  if (percentage < 80) return '#67c23a'
  if (percentage < 95) return '#e6a23c'
  return '#f56c6c'
}

// 磁盘使用率颜色
const getDiskColor = (percentage: number) => {
  if (percentage < 85) return '#67c23a'
  if (percentage < 95) return '#e6a23c'
  return '#f56c6c'
}

// 获取日志类型
const getLogType = (level: string): 'success' | 'warning' | 'info' | 'primary' | 'danger' => {
  const typeMap: Record<string, 'success' | 'warning' | 'info' | 'primary' | 'danger'> = {
    error: 'danger',
    warning: 'warning',
    info: 'info',
    success: 'success'
  }
  return typeMap[level] || 'info'
}

// 模拟加载节点列表
onMounted(() => {
  loadNodeList()
})

// 加载节点列表
const loadNodeList = async () => {
  loading.value = true
  try {
    const result = await getNodeList()
    if (result.code === 200) {
      // 转换API返回的数据格式为列表格式
      nodeList.value = Object.entries(result.data).map(([key, node]) => ({
        id: node.service_id,
        name: node.service_name,
        ip: node.service_addr,
        port: node.service_port,
        status: node.status,
        updated_at: new Date().toLocaleString(),
        cpuUsage: node.cpu_usage,
        memoryUsage: node.memory_usage,
        diskUsage: node.disk_usage,
        networkUsage: node.network_usage,
        connectionCount: node.connection_count,
        userCount: node.user_count,
        maxConnections: node.max_connections,
        maxConnTime: node.max_conn_time,
        maxNetworkUsage: node.max_network_usage,
        temperature: node.temperature
      }))
    } else {
      ElMessage.error(result.msg || '获取节点列表失败')
    }
  } catch (error) {
    console.error('获取节点列表出错:', error)
    ElMessage.error('获取节点列表失败，请重试')
  } finally {
    loading.value = false
  }
}

// 刷新节点列表
const refresh = () => {
  loadNodeList()
  ElMessage.success('节点列表已刷新')
}

// 打开添加节点对话框
const openAddNodeDialog = () => {
  isEdit.value = false
  Object.assign(configForm, {
    id: '',
    name: '',
    ip: '',
    port: 8080,
    type: '',
    description: ''
  })
  configVisible.value = true
}

// 打开节点详情
const openDetail = (node: any) => {
  Object.assign(currentNode, node)
  detailVisible.value = true
}

// 打开节点配置
const openConfig = (node: any) => {
  isEdit.value = true
  Object.assign(configForm, {
    id: node.id,
    name: node.name,
    ip: node.ip,
    port: node.port,
    type: node.type,
    description: node.description || ''
  })
  configVisible.value = true
}

// 保存节点配置
const saveConfig = async () => {
  if (!configFormRef.value) return

  await configFormRef.value.validate((valid, fields) => {
    if (valid) {
      // 模拟保存
      if (isEdit.value) {
        const index = nodeList.value.findIndex((item) => item.id === configForm.id)
        if (index !== -1) {
          nodeList.value[index] = {
            ...nodeList.value[index],
            name: configForm.name,
            ip: configForm.ip,
            port: configForm.port,
            type: configForm.type,
            description: configForm.description
          }
          ElMessage.success('节点配置已更新')
        }
      } else {
        const newNode = {
          id: Date.now(),
          name: configForm.name,
          ip: configForm.ip,
          port: configForm.port,
          type: configForm.type,
          description: configForm.description,
          status: 'online',
          registerTime: new Date().toLocaleString(),
          lastHeartbeat: new Date().toLocaleString(),
          apiVersion: 'v1.0.0',
          systemInfo: 'Linux x64',
          cpuUsage: Math.floor(Math.random() * 30) + 10,
          memoryUsage: Math.floor(Math.random() * 40) + 20,
          diskUsage: Math.floor(Math.random() * 50) + 30
        }
        nodeList.value.unshift(newNode)
        ElMessage.success('节点注册成功')
      }
      configVisible.value = false
    } else {
      console.log('验证失败:', fields)
    }
  })
}

// 删除节点
const removeNode = (node: any) => {
  ElMessageBox.confirm(`确定要删除节点 "${node.name}" 吗？`, '删除确认', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  })
    .then(() => {
      nodeList.value = nodeList.value.filter((item) => item.id !== node.id)
      ElMessage.success('节点已删除')
    })
    .catch(() => {})
}

// 批量删除节点
const batchDelete = () => {
  if (selectedNodes.value.length === 0) return

  const nodeNames = selectedNodes.value.map((node) => node.name).join('、')
  ElMessageBox.confirm(`确定要删除以下节点吗？\n${nodeNames}`, '批量删除确认', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  })
    .then(() => {
      const ids = selectedNodes.value.map((node) => node.id)
      nodeList.value = nodeList.value.filter((item) => !ids.includes(item.id))
      ElMessage.success(`已删除 ${selectedNodes.value.length} 个节点`)
      selectedNodes.value = []
    })
    .catch(() => {})
}

// 表格选择变化
const handleSelectionChange = (selection: any[]) => {
  selectedNodes.value = selection
}

// 获取服务类型名称
const getServiceTypeName = (type: string) => {
  const typeMap: Record<string, string> = {
    cloud: '云手机服务',
    local: '本地服务',
    web: 'Web服务',
    database: '数据库服务',
    cache: '缓存服务',
    mq: '消息队列',
    file: '文件服务',
    other: '其他服务'
  }
  return typeMap[type] || '未知'
}

// 获取状态类型
const getStatusType = (status: string): 'success' | 'warning' | 'info' | 'primary' | 'danger' => {
  const statusMap: Record<string, 'success' | 'warning' | 'info' | 'primary' | 'danger'> = {
    online: 'success',
    offline: 'danger',
    warning: 'warning'
  }
  return statusMap[status] || 'info'
}

// 获取状态名称
const getStatusName = (status: string) => {
  const statusMap: Record<string, string> = {
    online: '在线',
    offline: '离线',
    warning: '异常'
  }
  return statusMap[status] || '未知'
}

// 获取节点状态类型
const getNodeStatusType = (status: string): 'success' | 'info' | 'danger' => {
  if (!status) return 'info'
  return status === 'online' ? 'success' : 'danger'
}

// 获取节点状态名称
const getNodeStatusName = (status: string): string => {
  if (!status) return '未知'
  return status === 'online' ? '在线' : '离线'
}

// 生成模拟节点数据
const generateMockNodes = (count: number) => {
  const nodes = []
  const types = ['web', 'database', 'cache', 'mq', 'file', 'other']
  const statuses = ['online', 'offline', 'warning']

  for (let i = 0; i < count; i++) {
    const type = types[Math.floor(Math.random() * types.length)]
    const status = statuses[Math.floor(Math.random() * statuses.length)]
    
    const now = new Date()
    const days = Math.floor(Math.random() * 30)
    const hours = Math.floor(Math.random() * 24)
    const minutes = Math.floor(Math.random() * 60)
    const registerDate = new Date(now.getTime() - (days + 30) * 24 * 60 * 60 * 1000)
    const lastHeartbeatDate = new Date(now.getTime() - days * 24 * 60 * 60 * 1000 - hours * 60 * 60 * 1000 - minutes * 60 * 1000)

    nodes.push({
      id: i + 1,
      name: `${getServiceTypeName(type)}-${i + 1}`,
      ip: `192.168.1.${Math.floor(Math.random() * 254) + 1}`,
      port: Math.floor(Math.random() * 10000) + 1024,
      type,
      status,
      description: `这是一个${getServiceTypeName(type)}节点，提供相关服务。`,
      registerTime: registerDate.toLocaleString(),
      lastHeartbeat: lastHeartbeatDate.toLocaleString(),
      apiVersion: `v${Math.floor(Math.random() * 2) + 1}.${Math.floor(Math.random() * 10)}.${Math.floor(Math.random() * 10)}`,
      systemInfo: Math.random() > 0.5 ? 'Linux x64' : 'Windows x64',
      cpuUsage: Math.floor(Math.random() * 100),
      memoryUsage: Math.floor(Math.random() * 100),
      diskUsage: Math.floor(Math.random() * 100)
    })
  }

  return nodes
}

// 生成模拟日志记录
const generateMockLogs = () => {
  const logs = []
  const levels = ['info', 'warning', 'error', 'success']
  const messages = [
    '服务启动成功',
    '收到新的服务请求',
    '处理请求超时',
    '内存使用率过高',
    'CPU负载过高',
    '磁盘空间不足',
    '网络连接异常',
    '服务注册成功',
    '配置更新完成',
    '心跳检测超时'
  ]

  const logCount = Math.floor(Math.random() * 8) + 3
  const now = new Date()

  for (let i = 0; i < logCount; i++) {
    const minutes = Math.floor(Math.random() * 60)
    const seconds = Math.floor(Math.random() * 60)
    const logTime = new Date(now.getTime() - minutes * 60 * 1000 - seconds * 1000)

    logs.push({
      level: levels[Math.floor(Math.random() * levels.length)],
      message: messages[Math.floor(Math.random() * messages.length)],
      timestamp: logTime.toLocaleString()
    })
  }

  return logs.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())
}
</script>

<style lang="scss" scoped>
.page-content {
  width: 100%;
  height: 100%;

  .header {
    padding-bottom: 15px;
    border-bottom: 1px solid var(--art-border-color);

    h3 {
      font-size: 18px;
      font-weight: 500;
    }
  }

  .actions-bar {
    margin: 20px 0;
    
    .action-buttons {
      display: flex;
      justify-content: flex-end;
      gap: 10px;
    }
  }

  .node-stats {
    margin-bottom: 20px;
    
    .stat-item {
      display: flex;
      align-items: center;
      
      .stat-icon {
        width: 50px;
        height: 50px;
        border-radius: 10px;
        display: flex;
        align-items: center;
        justify-content: center;
        margin-right: 15px;
        
        .el-icon {
          font-size: 24px;
          color: white;
        }
        
        &.online {
          background-color: #67c23a;
        }
        
        &.offline {
          background-color: #f56c6c;
        }
        
        &.warning {
          background-color: #e6a23c;
        }
        
        &.total {
          background-color: #409eff;
        }
      }
      
      .stat-info {
        .stat-title {
          font-size: 14px;
          color: #909399;
        }
        
        .stat-value {
          font-size: 24px;
          font-weight: bold;
        }
      }
    }
  }

  .node-table {
    .pagination-container {
      margin-top: 20px;
      display: flex;
      justify-content: flex-end;
    }
  }

  .node-detail-tabs {
    margin-top: 20px;

    .health-info {
      .metric {
        display: flex;
        justify-content: center;
        align-items: center;
        padding: 20px 0;
      }
    }

    .log-container {
      max-height: 400px;
      overflow-y: auto;
      padding: 10px;
    }
  }
}

:deep(.el-card__header) {
  padding: 10px 20px;
  font-weight: 500;
}
</style> 